{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Anaconda 默认不包含 docx工具包，需要执行以下脚本进行安装\n",
    "# 如果本地没有安装工具包，请去掉“#”，再执行\n",
    "# !pip install -i https://mirrors.aliyun.com/pypi/simple/ python-docx"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1、导入包并创建一个 Word 文档对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 从docx 工具包中导入要使用的对象\n",
    "from docx import Document\n",
    "# 字号、大小单位：pt(点数或磅)、px(像素)、inch(英寸)、cm(厘米)\n",
    "from docx.shared import Pt,Inches \n",
    "from docx.enum.text import WD_PARAGRAPH_ALIGNMENT # 段落对齐\n",
    "\n",
    "# Document 不包含文件路径就是在内存中创建 Word 对象\n",
    "document = Document()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2、创建表格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 增加一个表格，有 0 行 2 列\n",
    "table = document.add_table(rows=0, cols=2)\n",
    "\n",
    "# data_list 列表中包含4个子列表，就是4行数据（第一行就是字段名分别是“对象”、“说明”）\n",
    "# 子列表包含2个元素就是2个列 \n",
    "data_list = [\n",
    "    ['对象', '说明'],\n",
    "    ['Document', '表示整个文档'],\n",
    "    ['Paragraph', '表示段落（每一次回车会产生新段落）'],\n",
    "    ['Run', '表示相同样式的文本延续']\n",
    "]\n",
    "\n",
    "# 遍历 data_list 列表（3行2列）\n",
    "# name:对象 desc:说明\n",
    "for name, desc in data_list:\n",
    "    # 增加一行，并获取单元格列表\n",
    "    row_cells = table.add_row().cells\n",
    "    # 写入数据\n",
    "    row_cells[0].text = name\n",
    "    row_cells[1].text = desc\n",
    "\n",
    "save_file = r'.\\files\\Word表格和图片.docx'\n",
    "# 保存内存中的document对象到文件\n",
    "document.save(save_file)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3、合并新增行的单元格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "表格有多少列： 2\n"
     ]
    }
   ],
   "source": [
    "# 增加一行，并获取单元格列表（准备合并单元格）\n",
    "row_cells = table.add_row().cells\n",
    "# 获取该表格的行数\n",
    "col_len = len(table.columns)\n",
    "print(\"表格有多少列：\",col_len)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "合并单元格后，段落数量： 1\n"
     ]
    }
   ],
   "source": [
    "# 第一列[0]、到第二列[1]单元格合并为一个单元格\n",
    "row_m_cell = row_cells[0].merge(row_cells[1]) # col_len - 1 = 2 - 1\n",
    "# 打印看看合并的单元格有多少个段落\n",
    "print(\"合并单元格后，段落数量：\", len(row_m_cell.paragraphs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第一个段落中的文字块数量： 0\n"
     ]
    }
   ],
   "source": [
    "# 获取单元格的第一个[0]段落对象\n",
    "row_m_cell_p = row_m_cell.paragraphs[0]\n",
    "print(\"第一个段落中的文字块数量：\", len(row_m_cell_p.runs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 增加文字块并填写文字\n",
    "row_m_cell_p.add_run('行合并')\n",
    "\n",
    "# 保存内存中的document对象到文件\n",
    "document.save(save_file)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4、合并新增列的单元格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 给表格新增一个新列\n",
    "new_col = table.add_column(Inches(2))\n",
    "# 获取新列的单元格\n",
    "col_cells = new_col.cells\n",
    "# 获取该表格的行数\n",
    "row_len = len(table.rows)\n",
    "print(\"表格有多少行：\",row_len)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 按列合并，从第一行[0]合并到最后一行[row_len - 1]，这里应该知道为什么要 减 1\n",
    "col_m_cell = col_cells[0].merge(col_cells[row_len - 1])\n",
    "# 获取 m_cell 中，第一个段落 \n",
    "col_m_cell_p = col_m_cell.paragraphs[0]\n",
    "# 增加文字块并填写文字\n",
    "col_m_cell_p.add_run('列合并')\n",
    "# 保存内存中的document对象到文件\n",
    "document.save(save_file)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5、增加图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 增加的分页也是一个段落（开始新的一页）\n",
    "document.add_page_break()\n",
    "\n",
    "# 增加图片，指定图片的文件路径，指定宽度\n",
    "document.add_picture(r'.\\images\\Word对象结构图.png',width=Inches(4))\n",
    "\n",
    "# 保存内存中的document对象到文件\n",
    "document.save(save_file)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 思考题\n",
    "\n",
    "1、尝试为创建表格的功能封装为一个函数，使得代码更简洁（不考虑合并单元格）。提示：参数为：data_list：列表中的列表\n",
    "\n",
    "2、用已学到的知识点完成一个有表格和图片的Word文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 思考题第 1 题答案（注意答案不是唯一的，仅仅作为参考）\n",
    "def create_table(records):\n",
    "    \"\"\"\n",
    "    使用方法：create_table(data_list)\n",
    "    :param records: 数据列表（列表中的列表，第一行是列名）\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    # 取第一行的列名\n",
    "    col_names = records[0]\n",
    "    # 增加一个表格，有 0 行 len(col_names) 列\n",
    "    new_table = document.add_table(rows=0, cols=len(col_names))\n",
    "\n",
    "    # 循环遍历 data_list 列表\n",
    "    for row_index, item in enumerate(records):\n",
    "        # 增加一行，并获取单元格列表\n",
    "        new_cells = new_table.add_row().cells\n",
    "        # 循环遍历列索引\n",
    "        for col_index, col_name in enumerate(col_names):\n",
    "            # 写入每列的数据\n",
    "            new_cells[col_index].text = item[col_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
